import {
  Inject,
  Controller,
  Body,
  UseGuard,
  Post,
  Files,
  Fields,
  Put,
  Get,
  Query,
} from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { PatientService } from '../service/api.patient.service';
import { RecordService } from '../service/api.record.service';
import {
  BloodRoutineIndicatorsDTO,
  UploadBloodSmearImagesDTO,
  SaveRecordDTO
} from '../dto/record';
import { Config } from '../dto/config'; // 引入类型
import flaskConfig from '../config/config.default';
const config = flaskConfig as Config;
import { DoctorGuard } from '../guard/doctor.guard';
import { UploadMiddleware } from '@midwayjs/busboy';
import { UploadFileInfo } from '@midwayjs/busboy';
import axios from 'axios';
import { uuidv7 } from 'uuidv7';
//import { AuthGuard } from '../guard/auth.guard';
@Controller('/record')
export class RecordController {
  @Inject()
  patientService: PatientService;
  @Inject()
  recordService: RecordService;
  @Inject()
  ctx: Context;
  /**
    * @name  getRecordHistory 查看患者历史记录
    * @param  {string} patientId  病人id
    * @return  object 病人历史记录
    */
  @UseGuard(DoctorGuard)
  @Get('/getRecordHistory')
  async getRecordHistory(
    @Query("patientId") patientId: string
  ): Promise<object> {
    return await this.recordService.getRecordHistory(patientId);
  }
  /**
   * @name getRecordDetails  查看记录详情
   * @param  {string} recordId  记录id
   * @return  object 记录详情
   */
  @UseGuard(DoctorGuard)
  @Get('/getRecordDetails')
  async getRecordDetails(
    @Query("recordId") recordId: string
  ): Promise<object> {
    return await this.recordService.getRecordDetails(recordId);
  }
  /**
   * @name   deleteRecord 保存患者记录信息
   * @param  {string} recordId  记录id
   * @returns {boolean} 返回结果
   */
  @UseGuard(DoctorGuard)
  @Put('/deleteRecord')
  async deleteRecord(@Body('recordId') recordId: string): Promise<boolean> {
    return await this.recordService.deleteRecord(recordId);
  }
  /**
   * @name   uploadBloodRoutineIndicators 上传患者血常规指标信息
   * @param  {BloodRoutineIndicatorsDTO}  bloodRoutineIndicatorsDTO  血常规指标信息列表
   * @returns {object} 返回结果
   */
  @UseGuard(DoctorGuard)
  @Post('/uploadBloodRoutineIndicators')
  async uploadBloodRoutineIndicators(
    @Body() bloodRoutineIndicatorsDTO: BloodRoutineIndicatorsDTO
  ): Promise<object> {
    const { patientId } = bloodRoutineIndicatorsDTO;
    const history = await this.recordService.getBloodRecordHistory(patientId);
    const { recordId, RBC, HGB, HCT, MCV, MCH, MCHC, RDW
  } =
  bloodRoutineIndicatorsDTO;
  const PredictedData = {
    patientId: patientId,
    recordId: recordId,
    bloodRoutineIndicators: [
      {
        红细胞计数: RBC,
        血红蛋白浓度: HGB,
        红细胞压积: HCT,
        平均红细胞体积: MCV,
        平均红细胞血红蛋白含量: MCH,
        平均红细胞血红蛋白浓度: MCHC,
        红细胞体积分布宽度: RDW,
      },
    ],
  };
  const PredictedProbability = await axios
    .post(`${config.flask.url}/predict`, PredictedData)
    .then(response => {
      const probabilities = response.data.probabilities[0];
      // 正确赋值
      return {
        地中海贫血: probabilities[0],
        正常: probabilities[1],
        缺铁性贫血: probabilities[2],
      };
    })
    .catch(error => {
      throw new Error('请求错误,模型预测失败');
    });
  const data = {
    history,
    PredictedProbability,
  };
    return data;
  }
/**
 * @name   uploadBloodSmearImages 上传患者血涂片信息
 * @param {File} files - 上传的图片文件
 * @param  {UploadBloodSmearImagesDTO}  uploadBloodSmearImagesDto  上传血涂片信息DTO
 * @return success 上传成功返回true，否则返回false
 */
@UseGuard(DoctorGuard)
@Put('/uploadBloodSmearImages', { middleware: [UploadMiddleware] })
async uploadBloodSmearImages(
  @Files('files') files: Array<UploadFileInfo>,
  @Fields() uploadBloodSmearImagesDto: UploadBloodSmearImagesDTO
): Promise < object > {
  if(files.length === 0 || files.length > 5) {
  throw new Error('错误的图片数量');
}
const { patientId, recordId } = uploadBloodSmearImagesDto;
const imageDetectionPromises = [];
const recordIdBase = recordId; // 保存原始的 recordId
for (let i = 0; i < files.length; i++) {
  const file = files[i];
  const uniqueRecordId = `${recordIdBase}(${i})`; // 生成唯一的 recordId
  imageDetectionPromises.push(
    this.processFile(patientId, uniqueRecordId, file)
  );
}
const imageDetectionResults = await Promise.all(imageDetectionPromises);
if (imageDetectionResults.length === 0) {
  throw new Error('上传失败');
}
return imageDetectionResults;
  }
/**
 * @name  saveRecord  查看患者历史记录
 * @param  {SaveRecordDTO} saveRecordDto 记录信息
 * @return  boolean 患者历史记录
 */
@UseGuard(DoctorGuard)
@Post('/saveRecord')
async saveRecord(@Body() saveRecordDto: SaveRecordDTO): Promise < boolean > {
  const { patientId, recordId } = saveRecordDto;
  const record = await this.recordService.getRecordById(recordId);
  if(record) {
    throw new Error('记录已存在,请勿重复提交');
  }
    const patient = await this.patientService.findPatientById(patientId);
  if(!patient) {
    throw new Error('患者不存在');
  }
    const newRecordId = uuidv7();
  const path = {
    patientId: patientId,
    recordId: recordId,
    newRecordId: newRecordId,
  };
  const res = await axios.put(`${config.flask.url}/saveRecord`, path);
  console.log(res);
  if(res.data.success){
  saveRecordDto.oldRecordId = recordId;
  saveRecordDto.recordId = newRecordId;
  return await this.recordService.saveRecord(saveRecordDto);
}else {
  throw new Error('保存失败');
}
  }
  // 处理文件
  private async processFile(
  patientId: string,
  recordId: string,
  file: UploadFileInfo
) {
  try {
    const path = {
      patientId: patientId,
      recordId: recordId,
      img: file.data,
    };
    const response = await axios.post(
      `${config.flask.url}/imageDetection`,
      path
    );
    const originalImageUrl = await this.recordService.saveOriginalImage(
      response.data.originalImageUrl
    );
    const details = await this.recordService.saveImageDetection(
      response.data.details
    );
    const total = response.data.total;
    const imgProbability = response.data.imgProbability;
    return {
      total,
      originalImageUrl,
      details,
      imgProbability,
    };
  } catch (error) {
    throw new Error(`Failed to process file ${file.filename}`);
  }
}
}
